package com.yi.wood.utils;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * @author MoYi
 * Created time 2019/6/6 14:23
 * 并发计数器：使用乐观锁（使用Unsafe类的CAS方式实现）
 */
public class Counter {
    private volatile long count;
    private static Unsafe unsafe;
    private static long offset;

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
            offset = unsafe.objectFieldOffset(Counter.class.getDeclaredField("count"));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public Counter(long count) {
        this.count = count;
    }

    public long increase() {
        long before = count;

        while (!unsafe.compareAndSwapLong(this, offset, before, before + 1)) {
            before = count;
        }
        return count;
    }

    public long getCount() {
        return count;
    }


    public static void main(String[] args) throws InterruptedException {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("counter-pool-%d").build();
        LinkedBlockingDeque<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<>(200);

        ExecutorService threadPool = new ThreadPoolExecutor(10,100,600, TimeUnit.MINUTES,
                linkedBlockingDeque,threadFactory, new ThreadPoolExecutor.AbortPolicy());
        Counter counter = new Counter(0);
        IntStream.range(0, 100).forEach(i -> {
            threadPool.submit(() -> {
                IntStream.range(0, 10000).forEach(j -> counter.increase());
            });
        });
        threadPool.shutdown();
        Thread.sleep(2000);
        System.out.println(counter.getCount());

    }


}
